package com.sky.service.admin.impl;

import com.sky.mapper.user.OrderDetailMapper;
import com.sky.mapper.user.OrderMapper;
import com.sky.mapper.user.UserMapper;
import com.sky.pojo.Orders;
import com.sky.result.Result;
import com.sky.service.admin.ReportService;
import com.sky.vo.OrderReportVO;
import com.sky.vo.SalesTop10ReportVO;
import com.sky.vo.TurnoverReportVO;
import com.sky.vo.UserReportVO;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;

@Service
public class ReportServiceImpl implements ReportService {


    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

//    @Override
//    public Result<TurnoverReportVO> turnoverStatistics(LocalDate begin, LocalDate end) {
//
//        List<String> dateList = new ArrayList<>();
//
//        //获取每一天的日期字符串
//        while (!begin.isAfter(end)){
//            dateList.add(begin.toString());
//            begin = begin.plusDays(1);
//        }
//        //遍历日期，查询每一天的营业额
//        List<Double> totalList = new ArrayList<>();
//        for (String date:dateList){
//            Double totalAmount = orderMapper.selectTotalAmountByDate(date);
//            if(totalAmount==null){
//                totalAmount=0.0;
//            }
//            totalList.add(totalAmount);
//        }
//        //组装数据
//        String dateString = StringUtils.join(dateList, ",");
//        String totalString = StringUtils.join(totalList, ",");
//        TurnoverReportVO vo = TurnoverReportVO.builder()
//                .dateList(dateString)
//                .turnoverList(totalString)
//                .build();
//
//        return Result.success(vo);
//    }

    @Override
    public Result<TurnoverReportVO> turnoverStatistics(LocalDate begin, LocalDate end) {

        List<String> dateList = new ArrayList<>();

        String start = begin.toString();

        //获取每一天的日期字符串
        while (!begin.isAfter(end)){
            dateList.add(begin.toString());
            begin = begin.plusDays(1);
        }

        //一条sql查询所有日期的营业总额
        List<Double> totalList = new ArrayList<>();
        /**
         *    {
         *        '2023-11-30':299.00,
         *        '2023-12-01':2444.00
         *
         *    }
         */
        Map<String, BigDecimal> res = orderMapper.selectAllDateTotalByDates(dateList,start,end.toString());
        dateList.forEach(date->{
            double total = res.get(date).doubleValue();
            totalList.add(total);
        });

        //组装数据
        String dateString = StringUtils.join(dateList, ",");
        String totalString = StringUtils.join(totalList, ",");
        TurnoverReportVO vo = TurnoverReportVO.builder()
                .dateList(dateString)
                .turnoverList(totalString)
                .build();

        return Result.success(vo);
    }


    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;

    @Override
    public Result<OrderReportVO> ordersStatistics(LocalDate begin, LocalDate end) {

        List<String> dateList = new ArrayList<>();

        String start = begin.toString();
        String endStr = end.toString();

        //获取每一天的日期字符串
        while (!begin.isAfter(end)){
            dateList.add(begin.toString());
            begin = begin.plusDays(1);
        }

        //1.查询指定时间段内的订单总数
        Future<Long> totalFuture = threadPoolExecutor.submit(() -> {
            return orderMapper.selectTotalByDateAndStatus(start, endStr, null);
        });
        //2.查询指定时间段内的有效订单数
        Future<Long> completedTotalFuture = threadPoolExecutor.submit(() -> {
            return orderMapper.selectTotalByDateAndStatus(start, endStr, Orders.COMPLETE_ORDER);
        });

        //4.查询指定时间段内的每一天的有效订单数
        Future<Map<String, Long>> map1Future = threadPoolExecutor.submit(() -> {
            /**
             *  {
             *      '2023-11-29':30,
             *      '2023-11-30':33
             *  }
             */
            return orderMapper.selectEveryDayTotalByDateAndStatus(start, endStr, dateList, Orders.COMPLETE_ORDER);
        });
        //5.查询指定时间段内的每一天的订单总数
        Future<Map<String, Long>> map2Future = threadPoolExecutor.submit(() -> {
            return orderMapper.selectEveryDayTotalByDateAndStatus(start, endStr, dateList, null);
        });

        Long total = 0l;
        Long completedTotal = 0l;
        Map<String,Long> map1 = new HashMap<>();
        Map<String,Long> map2 = new HashMap<>();
        try {
            total = totalFuture.get();
            completedTotal = completedTotalFuture.get();
            map1 = map1Future.get();
            map2 = map2Future.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }


        //3.统计有效订单率
        Double orderCompletionRate = completedTotal/(total*1.0);

        List<Long> everyDayOrderCountList = new ArrayList<>();
        List<Long> everyDayValidOrderCountList = new ArrayList<>();
        for(String date:dateList){
            Long everyDayOrderCount = map1.get(date);
            Long everyDayValidOrderCount = map2.get(date);
            everyDayOrderCountList.add(everyDayOrderCount);
            everyDayValidOrderCountList.add(everyDayValidOrderCount);
        };

        //组装数据
        OrderReportVO vo = OrderReportVO.builder()
                .dateList(StringUtils.join(dateList,","))
                .totalOrderCount(total.intValue())
                .validOrderCount(completedTotal.intValue())
                .orderCompletionRate(orderCompletionRate)
                .orderCountList(StringUtils.join(everyDayOrderCountList,","))
                .validOrderCountList(StringUtils.join(everyDayValidOrderCountList,","))
                .build();

        return Result.success(vo);
    }

    /*
        begin: 2023-11-29
        end:   2023-12-05
     */
    @Override
    public Result<UserReportVO> userStatistics(LocalDate begin, LocalDate end) {

        String start = begin.toString();
        List<String> dateList = new ArrayList<>();
        while (!begin.isAfter(end)){
            dateList.add(begin.toString());
            begin =begin.plusDays(1);
        }

        //指定时间段内 每日新增的用户数量
        /*
            {
                "2023-11-29":1,
                "2023-11-30":2
            }
         */
        Map<String,Long> map = userMapper.selectEveryDayIncrementCountByDate(start,end.toString(),dateList);
        //查询第一天之前的用户总数 ，后面的用户总数 只需要累计每日的新增数量即可
        Long total = userMapper.selectTotalBeforeDate(start);

        //解析结果中的每日新增用户数，用户总数
        List<Long> everyDayIncrementNum = new ArrayList<>();
        List<Long> beforeTotal = new ArrayList<>();
        for(String date:dateList){
            Long increment = map.get(date); //当日新增的用户数量
            everyDayIncrementNum.add(increment);
            total+=increment; // 截止当日的用户总数 = 当日之前的总数+当日的新增数量
            beforeTotal.add(total);
        }


        //组装结果
        UserReportVO vo = UserReportVO.builder()
                .dateList(StringUtils.join(dateList, ","))
                .newUserList(StringUtils.join(everyDayIncrementNum, ","))
                .totalUserList(StringUtils.join(beforeTotal, ","))
                .build();


        return Result.success(vo);
    }

    @Override
    public Result<SalesTop10ReportVO> top10(LocalDate begin, LocalDate end) {

        /**
            [
                {name:椰树牌椰汁,total:11},
            ]
         */
        List<Map<String,Object>> mapList =  orderDetailMapper.selectTop10ByDate(begin.toString(),end.toString());
        List<String> nameList = new ArrayList<>();
        List<String> numberList = new ArrayList<>();
        mapList.forEach(map->{
            String name = map.get("name").toString();
            String total = map.get("total").toString();
            nameList.add(name);
            numberList.add(total);
        });

        SalesTop10ReportVO vo = SalesTop10ReportVO.builder()
                            .nameList(StringUtils.join(nameList,","))
                            .numberList(StringUtils.join(numberList,","))
                            .build();

        return Result.success(vo);
    }

    @Override
    public void export(HttpServletResponse response) {


        //1.加载模板
        InputStream is = this.getClass().getClassLoader().getResourceAsStream("static/运营数据报表模板.xlsx");
        XSSFWorkbook excel = null;
        try {
            excel = new XSSFWorkbook(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //2.查询数据，造假
        //3.将数据写入到excel表格即可
        //第四行：
        XSSFSheet sheet1 = excel.getSheet("Sheet1");
        XSSFRow row4 = sheet1.getRow(3);
        //第三列
        row4.getCell(2).setCellValue(1200.50);
        //第五列
        row4.getCell(4).setCellValue("80%");
        //第7列
        row4.getCell(6).setCellValue(500);

        //第五行
        XSSFRow row5 = sheet1.getRow(4);
        row5.getCell(2).setCellValue(1345);
        row5.getCell(4).setCellValue(35.00);

        //4.响应给浏览器
        Calendar instance = Calendar.getInstance();
        int last = instance.getActualMaximum(Calendar.DAY_OF_MONTH);
        int first = instance.getActualMinimum(Calendar.DAY_OF_MONTH);

        instance.set(Calendar.DAY_OF_MONTH,first);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        //获取当月的第一天  2023-12-01
        String firstDay = format.format(instance.getTime());
        //获取当月的最后一天  2023-12-31
        instance.set(Calendar.DAY_OF_MONTH,last);
        String lastDay = format.format(instance.getTime());

        //时间遍历
        LocalDate begin = LocalDate.parse(firstDay);
        LocalDate end = LocalDate.parse(lastDay);

        int num = 7;
        while (!begin.isAfter(end)){
            System.out.println(num);
            //获取行
            XSSFRow row = sheet1.getRow(num);
            //设置行中列的值
            XSSFCell cell = row.getCell(1);
            row.getCell(1).setCellValue(begin.toString()); //日期
            row.getCell(2).setCellValue(300); //营业额
            row.getCell(3).setCellValue(28); //有效订单
            row.getCell(4).setCellValue("80%"); //订单完成率
            row.getCell(5).setCellValue(35.0); //平均客单价
            row.getCell(6).setCellValue(25); //新增用户数
            num++;
            begin = begin.plusDays(1);
        }

        //响应
        try {
            excel.write(response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
